package com.zhentao.listener;

import cn.hutool.crypto.digest.BCrypt;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.zhentao.domain.SClass;
import com.zhentao.domain.SMarketingdepartment;
import com.zhentao.domain.TUser;
import com.zhentao.domain.TUserRole;
import com.zhentao.service.TUserRoleService;
import com.zhentao.service.TUserService;

import javax.annotation.Resource;
import java.util.*;

public class UploadDataListener implements ReadListener<TUser> {
    @Resource
    private TUserService tUserService;

    public UploadDataListener(TUserService tUserService) {
        this.tUserService = tUserService;
    }

    /**
     * 每隔50条存储数据库，实际使用中可以根据需求调整
     */
    private static final int BATCH_COUNT = 50;

    /**
     * 缓存的数据
     */
    private List<TUser> cachedDataList = new ArrayList<>(BATCH_COUNT);

    // 用于存储已处理的用户标识，这里用户名是唯一标识
    private Set<String> processedUserNames = new HashSet<>();

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param tUser
     * @param analysisContext
     */
    @Override
    public void invoke(TUser tUser, AnalysisContext analysisContext) {
        // 先判断数据是否为空，如果不为空则加入缓存集合
        if (tUser!= null &&
                tUser.getMdName()!= null &&
                tUser.getSexName()!= null &&
                tUser.getClassName()!= null &&
                tUser.getNickname()!= null &&
                tUser.getUsername()!= null) {
            // 检查用户名是否已处理过，若未处理则添加到缓存集合
            if (!processedUserNames.contains(tUser.getUsername())) {
                processedUserNames.add(tUser.getUsername());
                cachedDataList.add(tUser);
            }
        }
        // 达到 BATCH_COUNT 了，需要去存储一次数据库，防止数据过多在内存中导致OOM
        if (cachedDataList.size() <= BATCH_COUNT) {
            //遍历集合
            for (TUser user : cachedDataList) {
                TUserRole userRole = new TUserRole();
                //查询数据库中相应的市场部
                SMarketingdepartment market = tUserService.getMarketAndSex(user.getMdName());
                user.setMdId(market.getId());
                //将性别进行转换0：男 1：女
                if (user.getSexName().equals("男")){
                    tUser.setSex(0);
                }else if (user.getSexName().equals("女")){
                    tUser.setSex(1);
                }
                //查询数据库中班级对应的值
                SClass classAndSex = tUserService.getClassAndSex(user.getClassName());
                user.setClassId(classAndSex.getClassId());
                // 设置默认密码
                user.setPassword(BCrypt.hashpw("123456"));
                // 保证随机数为10位数
                Random random = new Random();
                long randomNumber;
                do {
                    randomNumber = Math.abs(random.nextLong() % 10000000000L);
                } while (randomNumber < 0);
                String formattedId = String.format("%010d", randomNumber);
                tUser.setStudentId(formattedId);
                tUser.setPhone(tUser.getUsername());
                tUserService.save(user);
                userRole.setUserRoleId(null);
                userRole.setUId(user.getUserId());
                userRole.setRId(3);
                tUserService.saveRole(userRole);
            }
            // 清空缓存集合，方便内存回收
            cachedDataList.clear();
        }
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
        if (!cachedDataList.isEmpty()) {
            // 执行批量保存操作
            tUserService.saveBatch(cachedDataList);
        }
    }
}